package com.xbongbong.saas.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.pro.invoice.pojo.dto.InvoiceAmountDetailDTO;
import com.xbongbong.pro.invoice.pojo.dto.InvoiceAmountDetailGetDTO;
import com.xbongbong.pro.invoice.pojo.dto.SalesInvoiceAmountHandleDTO;
import com.xbongbong.pro.purchaseinvoice.dto.InvoiceAmountHandleDTO;
import com.xbongbong.pro.purchaseinvoice.dto.PurchaseInvoiceAmountDetailGetDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.InvoiceConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.enums.business.PayPlanEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.PurchaseInvoiceEnum;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;

/**
 * @author 胡国军
 */
public class InvoiceCommonHelp {

    /**
     *
     * @param data
     * @param amountDetail 发票金额
     * @param originId 源发票id
     * @param isImport
     * @param businessType 进项发票或者销项发票
     * @return void
     * @author 胡国军
     * @date 2022/7/28 17:10
     * @throws XbbException
     */
    public static void getMinusAmountFormRedInvoice(JSONObject data, JSONArray amountDetail, Long originId, Integer isImport, Integer businessType){
        if(originId > 0L && !Objects.equals(isImport,BasicConstant.ONE)) {
            if (Objects.nonNull(data)) {
                if(Objects.equals(businessType,XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
                    double invoiceAmount = data.getDouble(PurchaseInvoiceEnum.TOTAL_MONEY.getAttr());
                    data.put(PurchaseInvoiceEnum.TOTAL_MONEY.getAttr(), -invoiceAmount);
                }else if(Objects.equals(businessType,XbbRefTypeEnum.INVOICE.getCode())){
                    double invoiceAmount = data.getDouble(InvoiceEnum.TOTAL_MONEY.getAttr());
                    data.put(InvoiceEnum.TOTAL_MONEY.getAttr(), -invoiceAmount);
                }

            }
            if (CollectionsUtil.isNotEmpty(amountDetail)) {
                for (int i = 0; i < amountDetail.size(); i++) {
                    JSONObject amountObject = amountDetail.getJSONObject(i);
                    double maxInvoiceAmount = 0D;
                    double minInvoiceAmount = 0D;
                    double invoiceAmount = 0D;
                    double sumAmount = 0D;
                    maxInvoiceAmount = amountObject.getDouble(InvoiceConstant.MAX_INVOICE_AMOUNT);
                    minInvoiceAmount = amountObject.getDouble(InvoiceConstant.MIN_INVOICE_AMOUNT);
                    if(maxInvoiceAmount != 0D){
                        amountObject.put(InvoiceConstant.MIN_INVOICE_AMOUNT, -maxInvoiceAmount);
                    }else {
                        amountObject.put(InvoiceConstant.MIN_INVOICE_AMOUNT, maxInvoiceAmount);
                    }
                    if(minInvoiceAmount != 0D){
                        amountObject.put(InvoiceConstant.MAX_INVOICE_AMOUNT, -minInvoiceAmount);
                    }else {
                        amountObject.put(InvoiceConstant.MAX_INVOICE_AMOUNT, minInvoiceAmount);
                    }
                    invoiceAmount = amountObject.getDouble(InvoiceConstant.INVOICE_AMOUNT);
                    amountObject.put(InvoiceConstant.INVOICE_AMOUNT, -invoiceAmount);
                    sumAmount = amountObject.getDouble(InvoiceConstant.SUM_AMOUNT);
                    amountObject.put(InvoiceConstant.SUM_AMOUNT, -sumAmount);
                }
            }
        }
    }

    /**
     * 根据id 进行排序
     * @param <T>
     * @param idList
     * @param sourceList
     * @return
     */
    public static <T> List<T> sortEntityById(List<Long> idList, List<T> sourceList, Class clazz){
        List<PaasFormDataEntityExt> paasFormDataEntityExts = new ArrayList<>();
        List<PaasFormDataEntityExt> copyPaasFormDataEntityExts = new ArrayList<>();
        if(CollectionsUtil.isEmpty(sourceList)){
            return sourceList;
        }
        try {
            BeanUtil.copyPropertiesList(sourceList, copyPaasFormDataEntityExts,clazz);
        }catch (Exception e){
            return sourceList;
        }
        Map<Long,PaasFormDataEntityExt> sourceEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(CollectionsUtil.isNotEmpty(copyPaasFormDataEntityExts)){
            for(PaasFormDataEntityExt paasFormDataEntityExt : copyPaasFormDataEntityExts){
                sourceEntityMap.put(paasFormDataEntityExt.getId(),paasFormDataEntityExt);
            }
        }
        if(CollectionsUtil.isNotEmpty(idList)){
            for(Long id : idList){
                if(sourceEntityMap.containsKey(id)) {
                    paasFormDataEntityExts.add(sourceEntityMap.get(id));
                }
            }
        }
        if(paasFormDataEntityExts.size() == BasicConstant.ZERO){
            return sourceList;
        }

        return JSONArray.parseArray(JSONArray.toJSONString(paasFormDataEntityExts), clazz);
    }

    /**
     * 销项发票金额明细逻辑
     * 销项发票三期之合会有很大的变化,先分成两个方法,等改动稳定了之后再考虑
     * @param salesInvoiceAmountHandleDTO
     * @return
     */
    public static List<InvoiceAmountDetailDTO> commonPackageInvoiceAmountDetail(SalesInvoiceAmountHandleDTO salesInvoiceAmountHandleDTO){
        Map<Long,Double> contractInvoiceAmountMap = salesInvoiceAmountHandleDTO.getContractInvoiceAmountMap();
        Map<Long,Double> paymentInvoiceAmountMap = salesInvoiceAmountHandleDTO.getPaymentInvoiceAmountMap();
        Map<Long,Double> paymentSheetInvoiceAmountMap = salesInvoiceAmountHandleDTO.getPaymentSheetInvoiceAmountMap();
        List<InvoiceAmountDetailDTO> amountDetail = new ArrayList<>();
        List<PaasFormDataEntityExt> entityExts = null;
        List<PaasFormDataEntityExt> refEntityExts = null;
        Map<Long,PaasFormDataEntityExt> contractMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        boolean isEdit = false;
        boolean isGetDetail = Objects.equals(salesInvoiceAmountHandleDTO.getIsGetDetail(),BasicConstant.ONE);
        Map<Long,Double> sumContractUnInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //采购合同id 对应 关联数据 可开票金额
        Map<Long,Double> sumRefUnInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(Objects.equals(salesInvoiceAmountHandleDTO.getIsEdit(),BasicConstant.ONE)){
            isEdit = true;
        }
        boolean isContract = false;
        boolean isPayment = false;
        boolean isPaymentSheet = false;
        if(CollectionsUtil.isNotEmpty(salesInvoiceAmountHandleDTO.getContractEntityExts()) && CollectionsUtil.isEmpty(salesInvoiceAmountHandleDTO.getPaymentEntityExts())
                && CollectionsUtil.isEmpty(salesInvoiceAmountHandleDTO.getPaymentSheetEntityExts())){
            refEntityExts = new ArrayList<>(salesInvoiceAmountHandleDTO.getContractEntityExts());
            isContract = true;
        }
        if(CollectionsUtil.isNotEmpty(salesInvoiceAmountHandleDTO.getContractEntityExts()) && CollectionsUtil.isNotEmpty(salesInvoiceAmountHandleDTO.getPaymentEntityExts())
                && CollectionsUtil.isEmpty(salesInvoiceAmountHandleDTO.getPaymentSheetEntityExts())){
            refEntityExts = new ArrayList<>(salesInvoiceAmountHandleDTO.getPaymentEntityExts());
            entityExts = new ArrayList<>(salesInvoiceAmountHandleDTO.getContractEntityExts());
            isPayment = true;
        }
        if(CollectionsUtil.isNotEmpty(salesInvoiceAmountHandleDTO.getPaymentSheetEntityExts()) && CollectionsUtil.isEmpty(salesInvoiceAmountHandleDTO.getPaymentEntityExts())){
            if(CollectionsUtil.isNotEmpty(salesInvoiceAmountHandleDTO.getContractEntityExts())){
                entityExts = new ArrayList<>(salesInvoiceAmountHandleDTO.getContractEntityExts());
            }
            refEntityExts = new ArrayList<>(salesInvoiceAmountHandleDTO.getPaymentSheetEntityExts());
            isPaymentSheet = true;
        }
        //获取采购合同关系map
        if(CollectionsUtil.isNotEmpty(entityExts)){
            for(PaasFormDataEntityExt paasFormDataEntityExt : entityExts){
                contractMap.put(paasFormDataEntityExt.getId(),paasFormDataEntityExt);
            }
        }
        Map<Long,Double> refNowInvoiceAmount = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(CollectionsUtil.isNotEmpty(refEntityExts)){
            for(PaasFormDataEntityExt paasFormDataEntityExt : refEntityExts){
                List<JSONObject> contractList = new ArrayList<>();
                List<JSONObject> paymentList = new ArrayList<>();
                List<JSONObject> paymentSheetList = new ArrayList<>();
                JSONObject data = paasFormDataEntityExt.getData();
                Long contractId = 0L;
                double money = 0D;
                double invoiceAmount = 0D;
                double unInvoiceAmount = 0D;
                //取每个实体类对应的采购合同的id
                if(isPayment){
                    if(Objects.nonNull(data)) {
                        contractId = data.getLong(PaymentEnum.CONTRACT.getAttr());
                        money = data.getDouble(PaymentEnum.AMOUNT.getAttr());
                    }
                }

                if(isPaymentSheet){
                    if(CollectionsUtil.isNotEmpty(salesInvoiceAmountHandleDTO.getContractEntityExts())){
                        if(Objects.nonNull(data)) {
                            JSONArray contractIdList = data.getJSONArray(PaymentSheetEnum.CONTRACT.getAttr());
                            if(CollectionsUtil.isNotEmpty(contractIdList)) {
                                contractId = contractIdList.getLong(BasicConstant.ZERO);
                            }
                        }
                    }
                    money = data.getDouble(PaymentSheetEnum.AMOUNT.getAttr());
                }
                InvoiceAmountDetailDTO invoiceAmountDetailDTO = new InvoiceAmountDetailDTO();
                invoiceAmountDetailDTO.setCustomer(salesInvoiceAmountHandleDTO.getCustomerList());
                //放入采购合同
                if(isContract){
                    packageIdAndNameFormEntity(paasFormDataEntityExt,contractList);
                    invoiceAmountDetailDTO.setContract(contractList);
                    //取最大值
                    if(Objects.nonNull(data)) {
                        money = data.getDouble(ContractEnum.AMOUNT.getAttr());
                    }
                    if(Objects.nonNull(contractInvoiceAmountMap)){
                        invoiceAmount = contractInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getId(),0D);
                    }
                    invoiceAmountDetailDTO.setMaxInvoiceAmount(Arith.sub(money,invoiceAmount));
                    if(Objects.equals(salesInvoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
                        invoiceAmountDetailDTO.setMaxInvoiceAmount(invoiceAmount);
                    }
                    if(isEdit && !isGetDetail){
                        Map<Long,Double> oldContractInvoiceAmountMap = salesInvoiceAmountHandleDTO.getOldContractInvoiceAmountMap();
                        if(Objects.nonNull(oldContractInvoiceAmountMap)){
                            invoiceAmountDetailDTO.setInvoiceAmount(oldContractInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getId(),0D));
                        }
                    }else {
                        invoiceAmountDetailDTO.setInvoiceAmount(invoiceAmountDetailDTO.getMaxInvoiceAmount());
                    }
                    //如果采购合同可开票金额大于关联未开票金额
                    AddMapHelp.addMapNormal(sumRefUnInvoiceAmountMap,paasFormDataEntityExt.getId(),invoiceAmountDetailDTO.getMaxInvoiceAmount());

                }else {
                    PaasFormDataEntityExt  paasFormDataEntity = contractMap.get(contractId);
                    JSONObject contractData = null;
                    if(Objects.nonNull(paasFormDataEntity)){
                        contractData = paasFormDataEntity.getData();
                        packageIdAndNameFormEntity(paasFormDataEntity,contractList);
                        invoiceAmountDetailDTO.setContract(contractList);
                    }
                    double contractMoney = 0D;
                    double contractInvoiceAmount = 0D;
                    double contractUnInvoiceAmount = 0D;
                    if(Objects.nonNull(contractData)){
                        contractMoney = contractData.getDouble(ContractEnum.AMOUNT.getAttr());
                    }
                    if(Objects.nonNull(contractInvoiceAmountMap)){
                        if(Objects.nonNull(paasFormDataEntity)) {
                            contractInvoiceAmount = contractInvoiceAmountMap.getOrDefault(paasFormDataEntity.getId(), 0D);
                        }
                    }
                    if(isPayment) {
                        if (Objects.nonNull(paymentInvoiceAmountMap)) {
                            invoiceAmount = paymentInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getId(), 0D);
                        }
                    }
                    if(isPaymentSheet){
                        if (Objects.nonNull(paymentSheetInvoiceAmountMap)) {
                            invoiceAmount = paymentSheetInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getId(), 0D);
                        }
                    }
                    contractUnInvoiceAmount = Arith.sub(contractMoney,contractInvoiceAmount);
                    unInvoiceAmount = Arith.sub(money,invoiceAmount);
                    invoiceAmountDetailDTO.setMaxInvoiceAmount(unInvoiceAmount);

                    if(Objects.equals(salesInvoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
                        invoiceAmountDetailDTO.setMaxInvoiceAmount(invoiceAmount);
                    }

                    if(isEdit && !isGetDetail){
                        Map<Long,Double> oldPaymentInvoiceAmountMap = salesInvoiceAmountHandleDTO.getOldPaymentInvoiceAmountMap();
                        Map<Long,Double> oldPaymentSheetInvoiceAmountMap = salesInvoiceAmountHandleDTO.getOldPaymentSheetInvoiceAmountMap();
                        if(isPayment) {
                            if (Objects.nonNull(oldPaymentInvoiceAmountMap)) {
                                if(Objects.equals(salesInvoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
                                    invoiceAmountDetailDTO.setMaxInvoiceAmount(-invoiceAmountDetailDTO.getMaxInvoiceAmount());
                                }
                                invoiceAmountDetailDTO.setInvoiceAmount(oldPaymentInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getId(), 0D));
                            }
                        }
                        if(isPaymentSheet) {
                            if (Objects.nonNull(oldPaymentSheetInvoiceAmountMap)) {
                                if(Objects.equals(salesInvoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
                                    invoiceAmountDetailDTO.setMaxInvoiceAmount(-invoiceAmountDetailDTO.getMaxInvoiceAmount());
                                }
                                invoiceAmountDetailDTO.setInvoiceAmount(oldPaymentSheetInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getId(), 0D));
                            }
                        }

                    }else{
                        if(contractUnInvoiceAmount > unInvoiceAmount){
                            invoiceAmountDetailDTO.setInvoiceAmount(unInvoiceAmount);
                        }else {
                            if(isPaymentSheet){
                                if(CollectionsUtil.isEmpty(salesInvoiceAmountHandleDTO.getContractEntityExts())){
                                    double nowInvoiceAmount = refNowInvoiceAmount.getOrDefault(contractId,0D);
                                    invoiceAmountDetailDTO.setInvoiceAmount(Arith.sub(unInvoiceAmount,nowInvoiceAmount));
                                }else {
                                    double nowInvoiceAmount = refNowInvoiceAmount.getOrDefault(contractId,0D);
                                    invoiceAmountDetailDTO.setInvoiceAmount(Arith.sub(contractUnInvoiceAmount,nowInvoiceAmount));
                                    AddMapHelp.addMapNormal(refNowInvoiceAmount,contractId,invoiceAmountDetailDTO.getInvoiceAmount());
                                }
                            }else {
                                double nowInvoiceAmount = refNowInvoiceAmount.getOrDefault(contractId,0D);
                                invoiceAmountDetailDTO.setInvoiceAmount(Arith.sub(contractUnInvoiceAmount,nowInvoiceAmount));
                                AddMapHelp.addMapNormal(refNowInvoiceAmount,contractId,invoiceAmountDetailDTO.getInvoiceAmount());
                            }
                        }

                        if(Objects.equals(salesInvoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)) {
                            invoiceAmountDetailDTO.setInvoiceAmount(invoiceAmount);
                        }

                    }
                    //如果采购合同可开票金额大于关联未开票金额
                    if(isPaymentSheet && CollectionsUtil.isEmpty(salesInvoiceAmountHandleDTO.getContractEntityExts())){
                        AddMapHelp.addMapNormal(sumRefUnInvoiceAmountMap,paasFormDataEntityExt.getId(),unInvoiceAmount);
                    }else {
                        AddMapHelp.addMapNormal(sumRefUnInvoiceAmountMap,contractId,unInvoiceAmount);
                        sumContractUnInvoiceAmountMap.put(contractId,contractUnInvoiceAmount);
                    }
                }
                //放入付款计划
                if(isPayment){
                    packageIdAndNameFormEntity(paasFormDataEntityExt,paymentList);
                    invoiceAmountDetailDTO.setPayment(paymentList);
                }
                if(isPaymentSheet){
                    packageIdAndNameFormEntity(paasFormDataEntityExt,paymentSheetList);
                    invoiceAmountDetailDTO.setPaymentSheet(paymentSheetList);

                }
                if(Objects.equals(salesInvoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
                    invoiceAmountDetailDTO.setIsRed(BasicConstant.ONE);
                }
                invoiceAmountDetailDTO.setMinInvoiceAmount(BasicConstant.ZERO_DOUBLE);
                amountDetail.add(invoiceAmountDetailDTO);
            }
            double sumAmount = 0D;
            Iterator<Map.Entry<Long,Double>> iterator = sumRefUnInvoiceAmountMap.entrySet().iterator();
            while (iterator.hasNext()){
                Map.Entry<Long,Double> entry = iterator.next();
                Long id = entry.getKey();
                Double refUnInvoiceAmount = entry.getValue();
                Double contractUnInvoiceAmount = sumContractUnInvoiceAmountMap.getOrDefault(id,0D);
                if(contractUnInvoiceAmount < refUnInvoiceAmount){
                    if(isPaymentSheet && CollectionsUtil.isEmpty(salesInvoiceAmountHandleDTO.getContractEntityExts())){
                        sumAmount = Arith.add(sumAmount,refUnInvoiceAmount);
                    }else if(isContract) {
                        sumAmount = Arith.add(sumAmount,refUnInvoiceAmount);
                    }else {
                        sumAmount = Arith.add(sumAmount,contractUnInvoiceAmount);
                    }
                }else {
                    sumAmount = Arith.add(sumAmount,refUnInvoiceAmount);
                }
            }

            if(Objects.equals(salesInvoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
                sumAmount = 0D;
                for(InvoiceAmountDetailDTO invoiceAmountDetailDTO : amountDetail){
                    //区别于红冲 和 红冲编辑 红冲编辑可以让客户编辑成红冲原来的发票所以要控制到最大值
                    if(Objects.equals(salesInvoiceAmountHandleDTO.getIsEdit(),BasicConstant.ONE)){
                        sumAmount = Arith.add(sumAmount,invoiceAmountDetailDTO.getMaxInvoiceAmount());
                    }else {
                        sumAmount = Arith.add(sumAmount,invoiceAmountDetailDTO.getInvoiceAmount());
                    }
                }
                for(InvoiceAmountDetailDTO invoiceAmountDetailDTO : amountDetail){
                    invoiceAmountDetailDTO.setSumAmount(sumAmount);
                }
            }else {
                for(InvoiceAmountDetailDTO invoiceAmountDetailDTO : amountDetail){
                    invoiceAmountDetailDTO.setSumAmount(sumAmount);
                }
            }

        }
        if(isEdit && Objects.equals(salesInvoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
            getPositiveAmountFormRedInvoice(amountDetail);
        }
        return amountDetail;
    }

    public static void packageIdAndNameFormEntity(PaasFormDataEntityExt paasFormDataEntityExt,List<JSONObject> list){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(BasicConstant.ID,paasFormDataEntityExt.getId());
        jsonObject.put(BasicConstant.NAME,paasFormDataEntityExt.getSerialNo());
        list.add(jsonObject);
    }

    public static void getPositiveAmountFormRedInvoice(List<InvoiceAmountDetailDTO> invoiceAmountDetailDTOList){
        if(CollectionsUtil.isNotEmpty(invoiceAmountDetailDTOList)){
            for(InvoiceAmountDetailDTO invoiceAmountDetailDTO : invoiceAmountDetailDTOList){
                if(invoiceAmountDetailDTO.getInvoiceAmount() < 0D) {
                    invoiceAmountDetailDTO.setInvoiceAmount(-invoiceAmountDetailDTO.getInvoiceAmount());
                }
                if(invoiceAmountDetailDTO.getMaxInvoiceAmount() < 0D) {
                    invoiceAmountDetailDTO.setMaxInvoiceAmount(-invoiceAmountDetailDTO.getMaxInvoiceAmount());
                }
                invoiceAmountDetailDTO.setMinInvoiceAmount(BasicConstant.ZERO_DOUBLE);
                if(invoiceAmountDetailDTO.getSumAmount() < 0D) {
                    invoiceAmountDetailDTO.setSumAmount(-invoiceAmountDetailDTO.getSumAmount());
                }
            }
        }
    }

    public static InvoiceAmountDetailGetDTO getSalesAmountDetailsByInvoiceData(Long id,JSONObject data) throws XbbException{
        InvoiceAmountDetailGetDTO invoiceAmountDetailGetDTO = new InvoiceAmountDetailGetDTO();
        if(Objects.nonNull(data)){
            Integer isRed = getIntegerOrDefaultFromFormData(data,InvoiceEnum.IS_RED.getAttr(),BasicConstant.ZERO);
            invoiceAmountDetailGetDTO.setIsRed(isRed);
            Long customerId = FastJsonHelper.getLongOrDefaultFromFormData(data,InvoiceEnum.CUSTOMER_NAME.getAttr(),0L);
            List<Long> customerIdList = new ArrayList<>();
            customerIdList.add(customerId);
            JSONArray contractJson = data.getJSONArray(InvoiceEnum.CONTRACT_ID.getAttr());
            List<Long> contractIdList = null;
            List<Long> paymentIdList = null;
            List<Long> paymentSheetIdList = null;
            if(CollectionsUtil.isNotEmpty(contractJson)){
                contractIdList = JSONArray.parseArray(contractJson.toJSONString(),Long.class);
            }
            JSONArray paymentJson = data.getJSONArray(InvoiceEnum.PAYMENT_ID.getAttr());
            if(CollectionsUtil.isNotEmpty(paymentJson)){
                paymentIdList = JSONArray.parseArray(paymentJson.toJSONString(),Long.class);
            }
            JSONArray paymentSheetJson = data.getJSONArray(InvoiceEnum.PAYMENT_SHEET_ID.getAttr());
            if(CollectionsUtil.isNotEmpty(paymentSheetJson)){
                paymentSheetIdList = JSONArray.parseArray(paymentSheetJson.toJSONString(),Long.class);
            }
            invoiceAmountDetailGetDTO.setCustomerIdList(customerIdList);
            invoiceAmountDetailGetDTO.setContractIdList(contractIdList);
            invoiceAmountDetailGetDTO.setPaymentIdList(paymentIdList);
            invoiceAmountDetailGetDTO.setPaymentSheetIdList(paymentSheetIdList);
            invoiceAmountDetailGetDTO.setInvoiceId(id);
        }
        return invoiceAmountDetailGetDTO;
    }

    /**
     * 进项发票金额明细逻辑
     * 销项发票三期之合会有很大的变化,先分成两个方法,等改动稳定了之后再考虑
     * @param invoiceAmountHandleDTO
     * @return
     */
    public static List<InvoiceAmountDetailDTO> commonPackageAmountDetail2(InvoiceAmountHandleDTO invoiceAmountHandleDTO){
        Map<Long,Double> purchaseInvoiceAmountMap = invoiceAmountHandleDTO.getPurchaseInvoiceAmountMap();
        Map<Long,Double> payPlanInvoiceAmountMap = invoiceAmountHandleDTO.getPayPlanInvoiceAmountMap();
        Map<Long,Double> paySheetInvoiceAmountMap = invoiceAmountHandleDTO.getPaySheetInvoiceAmountMap();
        List<InvoiceAmountDetailDTO> amountDetail = new ArrayList<>();
        List<PaasFormDataEntityExt> entityExts = null;
        List<PaasFormDataEntityExt> refEntityExts = null;
        Map<Long,PaasFormDataEntityExt> purchaseMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        boolean isEdit = false;
        boolean isGetDetail = Objects.equals(invoiceAmountHandleDTO.getIsGetDetail(),BasicConstant.ONE);
        Map<Long,Double> sumPurchseUnInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //采购合同id 对应 关联数据 可开票金额
        Map<Long,Double> sumRefUnInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(Objects.equals(invoiceAmountHandleDTO.getIsEdit(),BasicConstant.ONE)){
            isEdit = true;
        }
        boolean isPurchase = false;
        boolean isPayPlan = false;
        boolean isPaySheet = false;
        if(CollectionsUtil.isNotEmpty(invoiceAmountHandleDTO.getPurchaseEntityExts()) && CollectionsUtil.isEmpty(invoiceAmountHandleDTO.getPayPlanEntityExts())
                && CollectionsUtil.isEmpty(invoiceAmountHandleDTO.getPaySheetEntityExtS())){
            refEntityExts = new ArrayList<>(invoiceAmountHandleDTO.getPurchaseEntityExts());
            isPurchase = true;
        }
        if(CollectionsUtil.isNotEmpty(invoiceAmountHandleDTO.getPurchaseEntityExts()) && CollectionsUtil.isNotEmpty(invoiceAmountHandleDTO.getPayPlanEntityExts())
                && CollectionsUtil.isEmpty(invoiceAmountHandleDTO.getPaySheetEntityExtS())){
            refEntityExts = new ArrayList<>(invoiceAmountHandleDTO.getPayPlanEntityExts());
            entityExts = new ArrayList<>(invoiceAmountHandleDTO.getPurchaseEntityExts());
            isPayPlan = true;
        }
        if(CollectionsUtil.isNotEmpty(invoiceAmountHandleDTO.getPaySheetEntityExtS()) && CollectionsUtil.isEmpty(invoiceAmountHandleDTO.getPayPlanEntityExts())){
            if(CollectionsUtil.isNotEmpty(invoiceAmountHandleDTO.getPurchaseEntityExts())){
                entityExts = new ArrayList<>(invoiceAmountHandleDTO.getPurchaseEntityExts());
            }
            refEntityExts = new ArrayList<>(invoiceAmountHandleDTO.getPaySheetEntityExtS());
            isPaySheet = true;
        }
        //获取采购合同关系map
        if(CollectionsUtil.isNotEmpty(entityExts)){
            for(PaasFormDataEntityExt paasFormDataEntityExt : entityExts){
                purchaseMap.put(paasFormDataEntityExt.getId(),paasFormDataEntityExt);
            }
        }
        Map<Long,Double> refNowInvoiceAmount = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(CollectionsUtil.isNotEmpty(refEntityExts)){
            for(PaasFormDataEntityExt paasFormDataEntityExt : refEntityExts){
                List<JSONObject> purchaseList = new ArrayList<>();
                List<JSONObject> payPlanList = new ArrayList<>();
                List<JSONObject> paySheetList = new ArrayList<>();
                JSONObject data = paasFormDataEntityExt.getData();
                Long purchaseId = 0L;
                double money = 0D;
                double invoiceAmount = 0D;
                double unInvoiceAmount = 0D;
                //取每个实体类对应的采购合同的id
                if(isPayPlan){
                    if(Objects.nonNull(data)) {
                        purchaseId = data.getLong(PayPlanEnum.LINK_PURCHASE.getAttr());
                        money = data.getDouble(PayPlanEnum.AMOUNT.getAttr());
                    }
                }

                if(isPaySheet){
                    if(CollectionsUtil.isNotEmpty(invoiceAmountHandleDTO.getPurchaseEntityExts())){
                        if(Objects.nonNull(data)) {
                            JSONArray purchaseIdList = data.getJSONArray(PaySheetEnum.LINK_PURCHASE.getAttr());
                            if(CollectionsUtil.isNotEmpty(purchaseIdList)) {
                                purchaseId = purchaseIdList.getLong(BasicConstant.ZERO);
                            }
                        }
                    }
                    money = data.getDouble(PaySheetEnum.AMOUNT.getAttr());
                }
                InvoiceAmountDetailDTO invoiceAmountDetailDTO = new InvoiceAmountDetailDTO();
                invoiceAmountDetailDTO.setSupplier(invoiceAmountHandleDTO.getSuppplierList());
                //放入采购合同
                if(isPurchase){
                    InvoiceCommonHelp.packageIdAndNameFormEntity(paasFormDataEntityExt,purchaseList);
                    invoiceAmountDetailDTO.setPurchase(purchaseList);
                    //取最大值
                    if(Objects.nonNull(data)) {
                        money = data.getDouble(PurchaseEnum.TOTAL_MONEY.getAttr());
                    }
                    if(Objects.nonNull(purchaseInvoiceAmountMap)){
                        invoiceAmount = purchaseInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getId(),0D);
                    }
                    invoiceAmountDetailDTO.setMaxInvoiceAmount(Arith.sub(money,invoiceAmount));
                    if(Objects.equals(invoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
                        invoiceAmountDetailDTO.setMaxInvoiceAmount(invoiceAmount);
                    }
                    if(isEdit && !isGetDetail){
                        Map<Long,Double> oldPurchaseInvoiceAmountMap = invoiceAmountHandleDTO.getOldPurchaseInvoiceAmountMap();
                        if(Objects.nonNull(oldPurchaseInvoiceAmountMap)){
                            //红冲发票编辑时 purchaseInvoiceAmountMap 这个里面是真实可开金额 oldPurchaseInvoiceAmountMap 是当前红冲可开金额
                                /*if(Objects.equals(invoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
                                    invoiceAmountDetailDTO.setMaxInvoiceAmount(oldPurchaseInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getId(), 0D));
                                }*/
                            invoiceAmountDetailDTO.setInvoiceAmount(oldPurchaseInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getId(),0D));
                        }
                    }else {
                        invoiceAmountDetailDTO.setInvoiceAmount(invoiceAmountDetailDTO.getMaxInvoiceAmount());
                    }
                    //如果采购合同可开票金额大于关联未开票金额
                    AddMapHelp.addMapNormal(sumRefUnInvoiceAmountMap,paasFormDataEntityExt.getId(),invoiceAmountDetailDTO.getMaxInvoiceAmount());

                }else {
                    PaasFormDataEntityExt  paasFormDataEntity = purchaseMap.get(purchaseId);
                    JSONObject purchaseData = null;
                    if(Objects.nonNull(paasFormDataEntity)){
                        purchaseData = paasFormDataEntity.getData();
                        InvoiceCommonHelp.packageIdAndNameFormEntity(paasFormDataEntity,purchaseList);
                        invoiceAmountDetailDTO.setPurchase(purchaseList);
                    }
                    double purchaseMoney = 0D;
                    double purchaseInvoiceAmount = 0D;
                    double purchaseUnInvoiceAmount = 0D;
                    if(Objects.nonNull(purchaseData)){
                        purchaseMoney = purchaseData.getDouble(PurchaseEnum.TOTAL_MONEY.getAttr());
                    }
                    if(Objects.nonNull(purchaseInvoiceAmountMap)){
                        if(Objects.nonNull(paasFormDataEntity)) {
                            purchaseInvoiceAmount = purchaseInvoiceAmountMap.getOrDefault(paasFormDataEntity.getId(), 0D);
                        }
                    }
                    if(isPayPlan) {
                        if (Objects.nonNull(payPlanInvoiceAmountMap)) {
                            invoiceAmount = payPlanInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getId(), 0D);
                        }
                    }
                    if(isPaySheet){
                        if (Objects.nonNull(paySheetInvoiceAmountMap)) {
                            invoiceAmount = paySheetInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getId(), 0D);
                        }
                    }
                    purchaseUnInvoiceAmount = Arith.sub(purchaseMoney,purchaseInvoiceAmount);
                    unInvoiceAmount = Arith.sub(money,invoiceAmount);
                    invoiceAmountDetailDTO.setMaxInvoiceAmount(unInvoiceAmount);
                    //if(invoiceAmountHandleDTO.getMoreTimeRed() > BasicConstant.ZERO){
                    if(Objects.equals(invoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
                        invoiceAmountDetailDTO.setMaxInvoiceAmount(invoiceAmount);
                    }
                    //}
                    if(isEdit && !isGetDetail){
                        Map<Long,Double> oldPayPlanInvoiceAmountMap = invoiceAmountHandleDTO.getOldPayPlanInvoiceAmountMap();
                        Map<Long,Double> oldPaySheetInvoiceAmountMap = invoiceAmountHandleDTO.getOldPaySheetInvoiceAmountMap();
                        if(isPayPlan ) {
                            if (Objects.nonNull(oldPayPlanInvoiceAmountMap)) {
                                if(Objects.equals(invoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
                                    invoiceAmountDetailDTO.setMaxInvoiceAmount(-invoiceAmountDetailDTO.getMaxInvoiceAmount());
                                }
                                invoiceAmountDetailDTO.setInvoiceAmount(oldPayPlanInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getId(), 0D));
                            }
                        }
                        if(isPaySheet) {
                            if (Objects.nonNull(oldPaySheetInvoiceAmountMap)) {
                                if(Objects.equals(invoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
                                    invoiceAmountDetailDTO.setMaxInvoiceAmount(-invoiceAmountDetailDTO.getMaxInvoiceAmount());
                                }
                                invoiceAmountDetailDTO.setInvoiceAmount(oldPaySheetInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getId(), 0D));
                            }
                        }

                    }else{
                        if(purchaseUnInvoiceAmount > unInvoiceAmount){
                            invoiceAmountDetailDTO.setInvoiceAmount(unInvoiceAmount);
                        }else {
                            if(isPaySheet){
                                if(CollectionsUtil.isEmpty(invoiceAmountHandleDTO.getPurchaseEntityExts())){
                                    double nowInvoiceAmount = refNowInvoiceAmount.getOrDefault(purchaseId,0D);
                                    invoiceAmountDetailDTO.setInvoiceAmount(Arith.sub(unInvoiceAmount,nowInvoiceAmount));
                                }else {
                                    double nowInvoiceAmount = refNowInvoiceAmount.getOrDefault(purchaseId,0D);
                                    invoiceAmountDetailDTO.setInvoiceAmount(Arith.sub(purchaseUnInvoiceAmount,nowInvoiceAmount));
                                    AddMapHelp.addMapNormal(refNowInvoiceAmount,purchaseId,invoiceAmountDetailDTO.getInvoiceAmount());
                                }
                            }else {
                                double nowInvoiceAmount = refNowInvoiceAmount.getOrDefault(purchaseId,0D);
                                invoiceAmountDetailDTO.setInvoiceAmount(Arith.sub(purchaseUnInvoiceAmount,nowInvoiceAmount));
                                AddMapHelp.addMapNormal(refNowInvoiceAmount,purchaseId,invoiceAmountDetailDTO.getInvoiceAmount());
                            }
                        }
                        //if(invoiceAmountHandleDTO.getMoreTimeRed() > BasicConstant.ZERO){
                        if(Objects.equals(invoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)) {
                            invoiceAmountDetailDTO.setInvoiceAmount(invoiceAmount);
                        }
                        //}
                    }
                    //如果采购合同可开票金额大于关联未开票金额
                    if(isPaySheet && CollectionsUtil.isEmpty(invoiceAmountHandleDTO.getPurchaseEntityExts())){
                        AddMapHelp.addMapNormal(sumRefUnInvoiceAmountMap,paasFormDataEntityExt.getId(),unInvoiceAmount);
                    }else {
                        AddMapHelp.addMapNormal(sumRefUnInvoiceAmountMap,purchaseId,unInvoiceAmount);
                        //saasSaveHelp.addMapNormal(sumPurchseUnInvoiceAmountMap,purchaseId,purchaseUnInvoiceAmount);
                        sumPurchseUnInvoiceAmountMap.put(purchaseId,purchaseUnInvoiceAmount);
                    }
                }
                //放入付款计划
                if(isPayPlan){
                    InvoiceCommonHelp.packageIdAndNameFormEntity(paasFormDataEntityExt,payPlanList);
                    invoiceAmountDetailDTO.setPayPlan(payPlanList);
                }
                if(isPaySheet){
                    InvoiceCommonHelp.packageIdAndNameFormEntity(paasFormDataEntityExt,paySheetList);
                    invoiceAmountDetailDTO.setPaySheet(paySheetList);

                }
                if(Objects.equals(invoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
                    invoiceAmountDetailDTO.setIsRed(BasicConstant.ONE);
                }
                invoiceAmountDetailDTO.setMinInvoiceAmount(BasicConstant.ZERO_DOUBLE);
                amountDetail.add(invoiceAmountDetailDTO);
            }
            double sumAmount = 0D;
            Iterator<Map.Entry<Long,Double>> iterator = sumRefUnInvoiceAmountMap.entrySet().iterator();
            while (iterator.hasNext()){
                Map.Entry<Long,Double> entry = iterator.next();
                Long id = entry.getKey();
                Double refUnInvoiceAmount = entry.getValue();
                Double purchaseUnInvoiceAmount = sumPurchseUnInvoiceAmountMap.getOrDefault(id,0D);
                if(purchaseUnInvoiceAmount < refUnInvoiceAmount){
                    if(isPaySheet && CollectionsUtil.isEmpty(invoiceAmountHandleDTO.getPurchaseEntityExts())){
                        sumAmount = Arith.add(sumAmount,refUnInvoiceAmount);
                    }else if(isPurchase) {
                        sumAmount = Arith.add(sumAmount,refUnInvoiceAmount);
                    }else {
                        sumAmount = Arith.add(sumAmount,purchaseUnInvoiceAmount);
                    }
                }else {
                    sumAmount = Arith.add(sumAmount,refUnInvoiceAmount);
                }
            }
            //if(invoiceAmountHandleDTO.getMoreTimeRed() > BasicConstant.ZERO){
            if(Objects.equals(invoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
                sumAmount = 0D;
                for(InvoiceAmountDetailDTO invoiceAmountDetailDTO : amountDetail){
                    //区别于红冲 和 红冲编辑 红冲编辑可以让客户编辑成红冲原来的发票所以要控制到最大值
                    if(Objects.equals(invoiceAmountHandleDTO.getIsEdit(),BasicConstant.ONE)){
                        sumAmount = Arith.add(sumAmount,invoiceAmountDetailDTO.getMaxInvoiceAmount());
                    }else {
                        sumAmount = Arith.add(sumAmount,invoiceAmountDetailDTO.getInvoiceAmount());
                    }
                }
                for(InvoiceAmountDetailDTO invoiceAmountDetailDTO : amountDetail){
                    invoiceAmountDetailDTO.setSumAmount(sumAmount);
                }
            }else {
                for(InvoiceAmountDetailDTO invoiceAmountDetailDTO : amountDetail){
                    invoiceAmountDetailDTO.setSumAmount(sumAmount);
                }
            }

        }
        if(isEdit && Objects.equals(invoiceAmountHandleDTO.getIsRed(),BasicConstant.ONE)){
            InvoiceCommonHelp.getPositiveAmountFormRedInvoice(amountDetail);
        }
        return amountDetail;
    }

    public static PurchaseInvoiceAmountDetailGetDTO getAmountDetailByInvoiceData(PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException{
        JSONObject data = paasFormDataEntityExt.getData();
        PurchaseInvoiceAmountDetailGetDTO purchaseInvoiceAmountDetailGetDTO = new PurchaseInvoiceAmountDetailGetDTO();
        if(Objects.nonNull(data)){
            Integer isRed = getIntegerOrDefaultFromFormData(data,PurchaseInvoiceEnum.IS_RED.getAttr(),BasicConstant.ZERO);
            purchaseInvoiceAmountDetailGetDTO.setIsRed(isRed);
            JSONArray supplierJson = data.getJSONArray(PurchaseInvoiceEnum.SUPPLIER_NAME.getAttr());
            List<Long> supplierIdList = getIdListByJSONArray(supplierJson);
            JSONArray purchaseJson = data.getJSONArray(PurchaseInvoiceEnum.PURCHASE_ID.getAttr());
            List<Long> purchaseIdList = getIdListByJSONArray(purchaseJson);
            JSONArray payPlanJson = data.getJSONArray(PurchaseInvoiceEnum.PAY_PLAN_ID.getAttr());
            List<Long> payPlanIdList = getIdListByJSONArray(payPlanJson);
            JSONArray paySheetJson = data.getJSONArray(PurchaseInvoiceEnum.PAY_SHEET_ID.getAttr());
            List<Long> paySheetList = getIdListByJSONArray(paySheetJson);
            purchaseInvoiceAmountDetailGetDTO.setSupplierIdList(supplierIdList);
            purchaseInvoiceAmountDetailGetDTO.setPurchaseIdList(purchaseIdList);
            purchaseInvoiceAmountDetailGetDTO.setPayPlanIdList(payPlanIdList);
            purchaseInvoiceAmountDetailGetDTO.setPaySheetIdList(paySheetList);
            purchaseInvoiceAmountDetailGetDTO.setPurchaseInvoiceId(paasFormDataEntityExt.getId());
        }
        return purchaseInvoiceAmountDetailGetDTO;
    }

    public static List<Long> getIdListByJSONArray(JSONArray jsonArray){
        List<Long> idList = new ArrayList<>();
        if(CollectionsUtil.isNotEmpty(jsonArray)) {
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                Long id = jsonObject.getLong(BasicConstant.ID);
                idList.add(id);
            }
        }
        return idList;
    }

    public static PurchaseInvoiceAmountDetailGetDTO getAmountDetailByInvoiceData(Long id,JSONObject data) throws XbbException{
        PurchaseInvoiceAmountDetailGetDTO purchaseInvoiceAmountDetailGetDTO = new PurchaseInvoiceAmountDetailGetDTO();
        if(Objects.nonNull(data)){
            Integer isRed = getIntegerOrDefaultFromFormData(data,PurchaseInvoiceEnum.IS_RED.getAttr(),BasicConstant.ZERO);
            purchaseInvoiceAmountDetailGetDTO.setIsRed(isRed);
            Long supplierId = FastJsonHelper.getLongOrDefaultFromFormData(data,PurchaseInvoiceEnum.SUPPLIER_NAME.getAttr(),0L);
            List<Long> supplierIdList = new ArrayList<>();
            supplierIdList.add(supplierId);
            JSONArray purchaseJson = data.getJSONArray(PurchaseInvoiceEnum.PURCHASE_ID.getAttr());
            List<Long> purchaseIdList = null;
            List<Long> payPlanIdList = null;
            List<Long> paySheetIdList = null;
            if(CollectionsUtil.isNotEmpty(purchaseJson)){
                purchaseIdList = JSONArray.parseArray(purchaseJson.toJSONString(),Long.class);
            }
            JSONArray payPlanJson = data.getJSONArray(PurchaseInvoiceEnum.PAY_PLAN_ID.getAttr());
            if(CollectionsUtil.isNotEmpty(payPlanJson)){
                payPlanIdList = JSONArray.parseArray(payPlanJson.toJSONString(),Long.class);
            }
            JSONArray paySheetJson = data.getJSONArray(PurchaseInvoiceEnum.PAY_SHEET_ID.getAttr());
            if(CollectionsUtil.isNotEmpty(paySheetJson)){
                paySheetIdList = JSONArray.parseArray(paySheetJson.toJSONString(),Long.class);
            }
            purchaseInvoiceAmountDetailGetDTO.setSupplierIdList(supplierIdList);
            purchaseInvoiceAmountDetailGetDTO.setPurchaseIdList(purchaseIdList);
            purchaseInvoiceAmountDetailGetDTO.setPayPlanIdList(payPlanIdList);
            purchaseInvoiceAmountDetailGetDTO.setPaySheetIdList(paySheetIdList);
            purchaseInvoiceAmountDetailGetDTO.setPurchaseInvoiceId(id);
        }
        return purchaseInvoiceAmountDetailGetDTO;
    }
}
